package cn.com.sinux.spring.utils;

import org.apache.commons.lang.StringUtils;
import org.apache.tools.zip.ZipEntry;
import org.apache.tools.zip.ZipOutputStream;
import org.slf4j.LoggerFactory;
import org.springframework.util.FileCopyUtils;

import java.io.*;
import java.util.ArrayList;
import java.util.Collections;
import java.util.LinkedList;
import java.util.List;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

/**
 * Created with IntelliJ IDEA.
 * User: New
 * Date: 13-4-1
 * Time: 下午2:51
 * To change this template use File | Settings | File Templates.
 */
public class FileUtils extends org.apache.commons.io.FileUtils {

    public static void write(InputStream inputStream, String path) {
        FileOutputStream outputStream = null;
        try {
            outputStream = new FileOutputStream(path);
            FileCopyUtils.copy(inputStream, outputStream);
        } catch (IOException ex) {
            LoggerFactory.getLogger(FileUtils.class).error("{}", ex.getMessage());
        } finally {
            try {
                inputStream.close();
                if (outputStream != null) {
                    outputStream.close();
                }
            } catch (IOException io) {
                LoggerFactory.getLogger(FileUtils.class).error("{}", io.getMessage());
            }
        }
    }

    public static void write(String sourcePath, String path) {
        InputStream stream = null;
        try {
            stream = new FileInputStream(sourcePath);
            write(stream, path);
        } catch (IOException ex) {
            LoggerFactory.getLogger(FileUtils.class).error("{}", ex.getMessage());
        }
    }

    /**
     * 创建文件夹
     *
     * @param path 相对路径
     * @return true/false
     */
    public static synchronized boolean createFolder(String path) {
        File file = new File(path);
        return !file.exists() && file.mkdir();
    }

    private static List<String> splitPath(String path) {
        if (StringUtils.isBlank(path)) {
            return Collections.EMPTY_LIST;
        }
        List<String> linkList = new LinkedList<String>();
        Pattern pattern = Pattern.compile("/[^/]{1,}");
        Matcher matcher = pattern.matcher(path);
        while (matcher.find()) {
            linkList.add(matcher.group());
        }
        return linkList;
    }

    public static String getExtName(String path) {
        if (StringUtils.isBlank(path) || path.lastIndexOf(".") == -1) {
            return StringUtils.EMPTY;
        }
        return path.substring(path.lastIndexOf(".") + 1).toLowerCase();
    }

    /**
     * 读取文件行，返回list
     *
     * @param file 文件
     * @return List, 每行一条记录
     * @throws java.io.IOException IO异常
     */
    public static List<String> readFile(File file) throws IOException {
        long maxLen = 50000;// 最大读取有效行数
        List<String> lineList = new LinkedList<String>();
        if (file.exists()) {
            long temp = 0;// 计数器
            InputStreamReader inputStreamReader = new InputStreamReader(new FileInputStream(file), "UTF-8");
            BufferedReader bufferedReader = new BufferedReader(inputStreamReader);
            try {
                String line = bufferedReader.readLine();
                while (line != null && temp < maxLen) {
                    if (StringUtils.isNotBlank(line.trim())) {
                        lineList.add(line);
                        temp++;

                    }
                    line = bufferedReader.readLine();
                }
                return lineList;
            } catch (Exception ex) {
                LoggerFactory.getLogger(FileUtils.class).error("ex is {}", ex);
                return Collections.emptyList();
            } finally {
                inputStreamReader.close();
                bufferedReader.close();
            }
        } else {
            return Collections.emptyList();
        }
    }

    public static List<String> getValues(InputStream inputStream, String code) {
        String str = null;
        List<String> results = new ArrayList<String>();
        try {
            BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(inputStream, code));
            while ((str = bufferedReader.readLine()) != null) {
                results.add(str);
            }
            inputStream.close();
            bufferedReader.close();
        } catch (IOException ex) {
            LoggerFactory.getLogger(FileUtils.class).error("ex is {}", ex);
            return Collections.emptyList();
        }
        return results;
    }

    /**
     * 复制一个源文件文件到一个目标文件 ，目标文件夹不存在时，将创建文件夹     ;
     * 可文件夹复制
     *
     * @param target  目标文件
     * @param src     源文件
     * @param replace 目标文件存在时，true表示替换，false，文件名加_copy_{number}
     */
    public static void copy(File src, File target, boolean replace) {

        if (target == null || null == src) {
            return;
        }

        //文件复制前检查
        if (!checkFilesPreCopy(src, target)) {
            return;
        }

        if (src.isDirectory()) {    //源文件是文件夹
            if (!target.exists()) {
                try {
                    target.mkdir();
                } catch (SecurityException e) {

                    LoggerFactory.getLogger(FileUtils.class).debug("创建目标文件夹时，遇到了问题：" + e.getMessage());
                    return;
                }
            }
            File[] fs = src.listFiles();
            if (fs != null) {
                for (File f : fs) {
                    File newF = new File(target, f.getName());
                    //copy文件夹
                    copy(f, newF, replace);
                }
            }

        } else {
            File realFile = target;
            if (!realFile.exists()) {
                try {
                    realFile.createNewFile();
                } catch (IOException e) {
                    LoggerFactory.getLogger(FileUtils.class).debug("创建目标文件时，遇到了问题：" + e.getMessage(), target.getAbsolutePath());
                    return;
                }
            } else {

                if (!replace) {//重名名
                    realFile = createNotExistsFile(target, 0);
                    try {
                        realFile.createNewFile();
                    } catch (IOException e) {
                        LoggerFactory.getLogger(FileUtils.class).debug("创建目标文件{}时，遇到了问题：" + e.getMessage(), realFile.getAbsolutePath());
                        return;
                    }
                }

            }

            try {
                doCopy(src, realFile);
            } catch (Exception e) {
                LoggerFactory.getLogger(FileUtils.class).debug("文件读取出现了问题");
                return;
            }
        }

    }

    /**
     * 文件byte复制
     *
     * @param src
     * @param realFile
     */
    private static void doCopy(File src, File realFile) throws Exception {
        FileOutputStream fileOutputStream = new FileOutputStream(realFile);
        FileInputStream fileInputStream = new FileInputStream(src);
        FileCopyUtils.copy(fileInputStream, fileOutputStream);
        fileOutputStream.close();
        fileInputStream.close();
    }

    /**
     * 得到一个不存在的文件
     *
     * @param f
     * @param baseNumber
     * @return
     */
    private static File createNotExistsFile(File f, int baseNumber) {
        if (!f.exists()) {
            return f;
        }
        File answer = new File(f.getParent(), f.getName() + "_copy_" + baseNumber);
        if (answer.exists()) {
            return createNotExistsFile(answer, baseNumber + 1);
        }
        return answer;
    }

    /**
     * 检查复制前创建文件夹及文件 是否可行，如重名文件与文件夹
     *
     * @param src
     * @param target
     * @return 是否成功！     s
     */
    private static boolean checkFilesPreCopy(File src, File target) {
        String message = "";
        boolean answer = false;
        //源文件不存在
        if (!src.exists()) {
            return answer;
        }
        //目标文件不存在
        if (!target.exists()) {

            boolean parentFileExists = true;
            //目标文件路径的父级文件不存在时，默认创建文件夹
            if (!target.getParentFile().exists()) {
                try {
                    parentFileExists = target.getParentFile().mkdirs();
                } catch (SecurityException e) {
                    message = e.getMessage();
                }
            }
            if (!parentFileExists) {
                LoggerFactory.getLogger(FileUtils.class).debug("创建目标文件的父级文件夹时，遇到了问题：" + message);
                return answer;
            }
        } else {
            if (src.isDirectory() && target.isFile()) {

                LoggerFactory.getLogger(FileUtils.class).debug("目标文件夹存在同名文件.");
                return answer;
            } else if (target.isDirectory() && src.isFile()) {

                LoggerFactory.getLogger(FileUtils.class).debug("目标文件存在同名文件夹.");
                return answer;
            }
        }
        return true;
    }

    public static boolean deleteFile(String filePath) {
        File file = new File(filePath);
        return file.exists() && file.delete();
    }

//    public static Runnable makeTreadWork(final String offHome, final int port, final String[] aa, final String[] ee) {
//        return new Runnable() {
//
//            public void run() {
////                String[] aa = new String[]{"D:/test/帮助提示模块.docx", "D:/test/部门排查工作方案.doc"};
////                String[] ee = new String[]{"D:/test/help", "D:/test/pub"};
//                List<ConvertSource> cc = null;
//                try {
//                    cc = toPdf(offHome, port, Arrays.asList(aa), false);
//                    for (int i = 0; i < cc.size(); i++) {
//                        List<String> result = cc.get(i).isConvertSuccess() ? pdf2Img(cc.get(i).getDest(), ee[i], true) : Collections.<String>emptyList();
//                        StringBuilder builder = new StringBuilder("生成图片:");
//                        for (String e : result) {
//                            builder.append(e).append(",");
//                        }
//                        System.out.println(builder);
//                    }
//                } catch (Exception e) {
//                    System.out.print(e.getMessage());
//                }
//
//            }
//        };
//    }

    public static void main(String[] args) throws Exception {
//        String[] aa = new String[]{"D:/test/帮助提示模块.docx", "D:/test/部门排查工作方案.doc", "D:/test/职业健康数据导入模板.xls", "D:/test/啊实打实.ppt"};
//        String[] ee = new String[]{"D:/test/help", "D:/test/pub", "D:/test/zy", "D:/test/aa"};
//        ExecutorService executorService = Executors.newFixedThreadPool(1);
//
//        executorService.shutdown();
    }

    public static void zip(File dir, ZipOutputStream zipOut, boolean directory) throws IOException {
        String pName = dir.getName();
        _zip(dir, directory || !dir.isDirectory() ? pName : "", zipOut);
        zipOut.closeEntry();
    }

    private static void _zip(File file, String p, ZipOutputStream zipOut) throws IOException {
        if (!file.isDirectory()) {
            zipOut.putNextEntry(new ZipEntry(p));
            copyFile(file, zipOut);
        } else {
            if(StringUtils.isNotBlank(p)){
                zipOut.putNextEntry(new ZipEntry(p + "/"));
            }
            File[] files = file.listFiles();
            if(files != null && files.length > 0){
                for (File f : files) {
                    _zip(f, p + "/" + f.getName(), zipOut);
                }
            }
        }
    }
}
